package io.renren.sf.controller;

import com.alibaba.fastjson.JSONObject;
import com.hz.common.utils.ResponseData;
import com.hz.common.utils.ResponsePage;
import com.hz.utils.FixedInformationName;
import com.hz.utils.MD5;
import io.renren.common.utils.*;
import io.renren.sf.entity.*;
import io.renren.sf.feign.OssFeign;
import io.renren.sf.service.*;
import io.renren.sf.vo.*;
import io.swagger.annotations.*;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


/**
 * @author cyl_txw
 * @email cyl_txw@gmail.com
 * @date 2023-05-09 15:02:11
 */
@RestController
@RequestMapping("sf/copybookCharacter")
@Api(tags = "字帖管理")
public class CopybookCharacterController {

    @Autowired
    private HzFixedInformationDicService fixedInformationDicService;

    @Autowired
    private HzCopybookCharacterInformationService coChrInformationService;

    @Autowired
    private HzCopybookCharacterService coChrService;

    @Autowired
    private OssFeign ossFeign;

    /**
     * 批量上传字帖资源
     */
    @ApiOperation("批量上传字帖资源")
    @PostMapping(value = "/copybookResource/upload", headers = "content-type=multipart/form-data")
    public ResponseData copybookResourceUpload(
            @ApiParam(value = "copybookResourceZip", required = true) MultipartFile copybookResourceZip) throws Exception {
        String timeMd5 = MD5.encrypt(new Date().getTime() + "");
        String dirPath = Constant.ZipCopybookResource.PATH.getName() + timeMd5;  // 压缩文件处理的路径
        String zipPath = dirPath + "/" + Constant.ZipCopybookResource.ZIPNAME.getName() + ".zip";  // 压缩包文件路径
        String descDir = dirPath + "/" + Constant.ZipCopybookResource.ZIPNAME.getName();  // 解压缩文件夹
        try {
            // 1检验资源是否符合要求
            // 文件大小校验
            // 2解压压缩包
            // 临时文件路径
            File copybookResourceTmpZip = new File(zipPath);
            FileUtils.copyInputStreamToFile(copybookResourceZip.getInputStream(), copybookResourceTmpZip);
            CompressUtil.decompress(zipPath, descDir);
            // CompressUtil.decompress("C:\\Users\\xw\\Desktop\\a\\字帖资源模板.zip");
            // 读取解压的文件
            // 新增字帖字--批量新增字帖字对应的字帖字信息list
            File file = new File(descDir);  // 解压缩的文件夹路径
            File[] copybookCharacterDirs = file.listFiles();
            for (File copybookCharacterDir : copybookCharacterDirs) {
                // 如果是文件直接pass
                if (copybookCharacterDir.isFile())
                    continue;
                String copybookCharacterName = copybookCharacterDir.getName();  // 字帖字的名字
                HzCopybookCharacterEntity copybookCharacter = new HzCopybookCharacterEntity(copybookCharacterName, new Date());
                // 保存字帖信息
                try {
                    coChrService.save(copybookCharacter);
                } catch (Exception e) {
                    // 保存出现失败
                    continue;
                }
                // 字帖字id
                Long cid = copybookCharacter.getId();
                // 新增字帖字对应的字帖字信息list
                File[] copybookCharacterInforFiles = copybookCharacterDir.listFiles();
                for (File copybookCharacterInforFile : copybookCharacterInforFiles) {
                    try {
                        // 如果是文件夹直接pass
                        if (copybookCharacterInforFile.isDirectory())
                            continue;
                        //
                        String[] names = copybookCharacterInforFile.getName().split("-|\\.");
                        // 排除字帖字信息的名称格式不一样情况
                        if (names.length < 3 || !(names[2].equals("png") || names[2].equals("jpg")))
                            continue;
                        // 查询出书体、书家对应的id，并排除不存在的书体或书家对应的字帖字信息
                        Long characterTypeId = fixedInformationDicService.getIdByTypeAndName(names[0], FixedInformationName.CO_CHR_CHARACTER_TYPE);
                        Long calligrapherId = fixedInformationDicService.getIdByTypeAndName(names[1], FixedInformationName.CO_CHR_CALLIGRAPHER);
                        if (characterTypeId == null || calligrapherId == null)
                            continue;
                        // 上传字帖字信息图片到oss上
                        R upload = ossFeign.uploadZip(copybookCharacterInforFile.getAbsolutePath());
                        String copybookCharacterUrl = (String) upload.get("url");

                        // 上传失败
                        if (copybookCharacterUrl == null || copybookCharacterUrl.equals(""))
                            continue;
                        // 新增字帖字信息记录
                        HzCopybookCharacterInformationEntity coChrInformation = new HzCopybookCharacterInformationEntity(copybookCharacterUrl,
                                copybookCharacterName,
                                names[0],
                                names[1],
                                cid);
                        coChrInformationService.save(coChrInformation);
                    } catch (Exception e) {
                        continue;
                    }
                }
            }
        } catch (Exception e){
            return ResponseData.error(500, "解压缩包出现错误");
        }finally {
            System.gc();
            System.runFinalization(); // 强制回收io流
            // 删除文件夹下的所有文件
            File dir = new File(dirPath);
            try {
                FileUtils.forceDelete(dir);
            }catch (Exception e){
                return ResponseData.error(500, "删除文件失败");
            }
        }
        return ResponseData.success("资源上传成功");
    }


    /**
     * 字帖字模糊分页查询
     */
    @ApiOperation("字帖字模糊分页查询")
    @PostMapping("/copybookCharacter/list")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "coChrName", value = "字帖字名称", paramType = "query", dataType = "String", required = false),
            @ApiImplicitParam(name = "curPage", value = "当前页数", paramType = "query", dataType = "Integer", required = true),
            @ApiImplicitParam(name = "pageSize", value = "页大小", paramType = "query", dataType = "Integer", required = true)
    })
    public ResponseData<ResponsePage<List<HzCopybookCharacterEntity>>> copybookCharacterPage(@RequestParam(name = "coChrName", required = false) String coChrName,
                                                            @RequestParam("curPage") Integer curPage,
                                                            @RequestParam("pageSize") Integer pageSize) {

        List<HzCopybookCharacterEntity> copybookCharacterList = coChrService.queryCopybookCharacter(curPage, pageSize, coChrName);

        ResponsePage<List<HzCopybookCharacterEntity>> page = new ResponsePage<>(
                copybookCharacterList,
                coChrService.queryCopybookCharacterNum(coChrName),
                pageSize
        );
        return ResponseData.success(page);
    }


    /**
     * 字帖字信息删除
     */
    @ApiOperation("字帖字信息删除")
    @PostMapping("/copybookInfor/delete")
    public ResponseData copybookInforDelete(@RequestBody Long[] ids){
        coChrInformationService.removeByIds(Arrays.asList(ids));
        return ResponseData.success("删除成功");
    }

    /**
     * 字帖字信息修改
     */
    @ApiOperation("字帖字信息修改")
    @PostMapping("/copybookInfor/update")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "字帖字信息id", paramType = "query", dataType = "Long", required = true),
            @ApiImplicitParam(name = "copybookCharacter", value = "字帖字src", paramType = "query", dataType = "String", required = true),
            @ApiImplicitParam(name = "characterTypeId", value = "字体种类id", paramType = "query", dataType = "Long", required = true),
            @ApiImplicitParam(name = "calligrapherId", value = "书家id", paramType = "query", dataType = "Long", required = true)
    })
    public ResponseData copybookInforUpdate(@RequestParam("id") Long id,
                                            @RequestParam("copybookCharacter") String copybookCharacter,
                                            @RequestParam("characterTypeId") Long characterTypeId,
                                            @RequestParam("calligrapherId") Long calligrapherId){
        // 根据字体种类id、书家id查询字体种类和书家是否存在
        HzFixedInformationDicEntity characterTypeDic = fixedInformationDicService.getById(characterTypeId);
        HzFixedInformationDicEntity calligrapherDic = fixedInformationDicService.getById(calligrapherId);
        if (calligrapherDic == null || characterTypeDic == null)
            return ResponseData.success("更新失败",false);
        String characterType = characterTypeDic.getFixedInformationContent();
        String calligrapher = calligrapherDic.getFixedInformationContent();

        HzCopybookCharacterInformationEntity coChrInformation = new HzCopybookCharacterInformationEntity(id,
                copybookCharacter,
                characterType,
                calligrapher);
        coChrInformationService.updateById(coChrInformation);
        return ResponseData.success("修改成功");
    }


    /**
     * 字帖字信息保存
     */
    @ApiOperation("字帖字信息保存")
    @PostMapping("/copybookInfor/save")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "copybookCharacter", value = "字帖字src", paramType = "query", dataType = "String", required = true),
            @ApiImplicitParam(name = "characterTypeId", value = "字体种类id", paramType = "query", dataType = "Long", required = true),
            @ApiImplicitParam(name = "calligrapherId", value = "书家id", paramType = "query", dataType = "Long", required = true),
            @ApiImplicitParam(name = "cid", value = "字帖字id", paramType = "query", dataType = "Long", required = true)
    })
    public ResponseData copybookInforSave(@RequestParam("copybookCharacter") String copybookCharacter,
                                          @RequestParam("characterTypeId") Long characterTypeId,
                                          @RequestParam("calligrapherId") Long calligrapherId,
                                          @RequestParam("cid") Long cid){
        // 根据字体种类id、书家id查询字体种类和书家是否存在
        HzFixedInformationDicEntity characterTypeDic = fixedInformationDicService.getById(characterTypeId);
        HzFixedInformationDicEntity calligrapherDic = fixedInformationDicService.getById(calligrapherId);
        if (calligrapherDic == null || characterTypeDic == null)
            return ResponseData.success("保存失败",false);
        String characterType = characterTypeDic.getFixedInformationContent();
        String calligrapher = calligrapherDic.getFixedInformationContent();
        // 根据cid获取字帖字
        HzCopybookCharacterEntity coCharacter = coChrService.getById(cid);

        HzCopybookCharacterInformationEntity coChrInformation = new HzCopybookCharacterInformationEntity(copybookCharacter,
                coCharacter.getCopybookCharacterName(),
                characterType,
                calligrapher,
                cid);
        coChrInformationService.save(coChrInformation);
        return ResponseData.success("保存成功");
    }


    /**
     * 字帖字修改
     */
    @ApiOperation("字帖字修改")
    @PostMapping("/copybookCharacter/update")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "字帖字id", paramType = "query", dataType = "Long", required = true),
            @ApiImplicitParam(name = "copybookCharacterName", value = "精临例字名称", paramType = "query", dataType = "String", required = true)
    })
    public ResponseData copybookCharacterUpdate(@RequestParam("id") long id,
                                                @RequestParam("copybookCharacterName") String copybookCharacterName){
        HzCopybookCharacterEntity copybookCharacter = new HzCopybookCharacterEntity(id, copybookCharacterName);
        coChrService.updateById(copybookCharacter);
        // 同步修改字帖字下面所有的字帖字信息
        coChrInformationService.updateAllRelatedCharacterName(id, copybookCharacterName);
        return ResponseData.success("修改成功");
    }

    /**
     * 字帖字删除
     */
    @ApiOperation("字帖字删除")
    @PostMapping("/copybookCharacter/delete")
    public ResponseData copybookCharacterDelete(@RequestBody Long[] ids){
        coChrService.removeByIds(Arrays.asList(ids));
        return ResponseData.success("删除成功");
    }

    /**
     * 字帖字保存
     */
    @ApiOperation("字帖字保存")
    @PostMapping("/copybookCharacter/save")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "copybookCharacterName", value = "精临例字名称", paramType = "query", dataType = "String", required = true)
    })
    public ResponseData copybookCharacterSave(@RequestParam("copybookCharacterName") String copybookCharacterName) {
        HzCopybookCharacterEntity copybookCharacter = new HzCopybookCharacterEntity(copybookCharacterName, new Date());
        coChrService.save(copybookCharacter);
        return ResponseData.success("保存成功");
    }

    /**
     * 字帖字体、书家获取
     */
    @ApiOperation("字帖字体、书家获取")
    @GetMapping("/cc/get")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "type", value = "查询类别。1字体，2书家", paramType = "query", dataType = "Integer", allowableValues = "1,2,3", required = true)
    })
    public ResponseData ccGet(@RequestParam("type") Integer type) {
        // 查询所有的字体、书家名称
        List<HzFixedInformationDicEntity> fixedInformationDicList;
        // 映射成vo List
        switch (type){
            case 1 :
                fixedInformationDicList = fixedInformationDicService.queryByName(FixedInformationName.CO_CHR_CHARACTER_TYPE);
                List<CopybookCharacterTypeVo> copybookCharacterTypeList = fixedInformationDicList.stream()
                        .map(fixedInformationDic -> new CopybookCharacterTypeVo(fixedInformationDic.getId(),
                                fixedInformationDic.getFixedInformationContent(),
                                fixedInformationDic.getUpdatetime(),
                                fixedInformationDic.getIorder()))
                        .collect(Collectors.toList());
                return ResponseData.success(copybookCharacterTypeList);
            case 2 :
                fixedInformationDicList = fixedInformationDicService.queryByName(FixedInformationName.CO_CHR_CALLIGRAPHER);
                List<CopybookCalligrapherVo> copybookCalligrapherList = fixedInformationDicList.stream()
                        .map(fixedInformationDic -> new CopybookCalligrapherVo(fixedInformationDic.getId(),
                                fixedInformationDic.getFixedInformationContent(),
                                fixedInformationDic.getUpdatetime(),
                                fixedInformationDic.getIorder()))
                        .collect(Collectors.toList());
                return ResponseData.success(copybookCalligrapherList);
        }
        return ResponseData.success("类别参数错误！");
    }

    /**
     * 字体、书家分页
     */
    @ApiOperation("字体、书家分页列表")
    @GetMapping("/cc/list")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "type", value = "查询类别。1字体，2书家", paramType = "query", dataType = "Integer", allowableValues = "1,2,3", required = true),
            @ApiImplicitParam(name = "curPage", value = "当前页数", paramType = "query", dataType = "Integer", required = true),
            @ApiImplicitParam(name = "pageSize", value = "页大小", paramType = "query", dataType = "Integer", required = true)
    })
    public ResponseData<JSONObject> ccPage(@RequestParam("type") Integer type,
                                            @RequestParam("curPage") Integer curPage,
                                            @RequestParam("pageSize") Integer pageSize) {
        List<HzFixedInformationDicEntity> fixedInformationDics;
        JSONObject json = new JSONObject();
        switch (type){
            case 1 :
                fixedInformationDics = fixedInformationDicService.queryYears(curPage, pageSize, FixedInformationName.CO_CHR_CHARACTER_TYPE);
                List<CopybookCharacterTypeVo> copybookCharacterTypeList = fixedInformationDics.stream()
                        .map(fixedInformationDic -> new CopybookCharacterTypeVo(fixedInformationDic.getId(),
                                fixedInformationDic.getFixedInformationContent(),
                                fixedInformationDic.getUpdatetime(),
                                fixedInformationDic.getIorder()))
                        .collect(Collectors.toList());
                json.put("record",copybookCharacterTypeList);
                json.put("total",fixedInformationDicService.queryFixedInformationDicsNum(FixedInformationName.CO_CHR_CHARACTER_TYPE));
                break;
            case 2 :
                fixedInformationDics = fixedInformationDicService.queryYears(curPage, pageSize, FixedInformationName.CO_CHR_CALLIGRAPHER);
                List<CopybookCalligrapherVo> copybookCalligrapherList = fixedInformationDics.stream()
                        .map(fixedInformationDic -> new CopybookCalligrapherVo(fixedInformationDic.getId(),
                                fixedInformationDic.getFixedInformationContent(),
                                fixedInformationDic.getUpdatetime(),
                                fixedInformationDic.getIorder()))
                        .collect(Collectors.toList());
                json.put("record",copybookCalligrapherList);
                json.put("total",fixedInformationDicService.queryFixedInformationDicsNum(FixedInformationName.CO_CHR_CALLIGRAPHER));
                break;
            default:
                json.put("record", null);
                json.put("total", 0);
                break;
        }
        json.put("size",pageSize);
        return ResponseData.success(json);
    }


    /**
     * 字体、书家保存
     */
    @ApiOperation("字体、书家保存")
    @PostMapping("/cc/save")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "type", value = "保存类别。1字体，2书家", paramType = "query", dataType = "Integer", allowableValues = "1,2", required = true),
            @ApiImplicitParam(name = "name", value = "书家名称", paramType = "query", dataType = "String", required = true),
            @ApiImplicitParam(name = "order", value = "顺序", paramType = "query", dataType = "int", required = true)
    })
    public ResponseData ccSave(@RequestParam("type") Integer type,
                               @RequestParam("name") String name,
                               @RequestParam("order") Integer order){
        HzFixedInformationDicEntity fixedInformationDic = new HzFixedInformationDicEntity(name, new Date(), order);
        switch (type) {
            case 1:
                fixedInformationDic.setFixedInformationName(FixedInformationName.CO_CHR_CHARACTER_TYPE);
                break;
            case 2:
                fixedInformationDic.setFixedInformationName(FixedInformationName.CO_CHR_CALLIGRAPHER);
                break;
            default:
                return ResponseData.success("保存类别参数错误");
        }
        fixedInformationDicService.save(fixedInformationDic);
        return ResponseData.success("保存成功");
    }

    /**
     * 字体、书家修改
     */
    @ApiOperation("字体、书家修改")
    @PostMapping("/cc/update")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "type", value = "修改类别。1字体，2书家", paramType = "query", dataType = "Integer", allowableValues = "1,2", required = true),
            @ApiImplicitParam(name = "id", value = "字体、书家id", paramType = "query", dataType = "Long", required = true),
            @ApiImplicitParam(name = "name", value = "字体、书家名称", paramType = "query", dataType = "String", required = true),
            @ApiImplicitParam(name = "order", value = "顺序", paramType = "query", dataType = "int", required = true)
    })
    public ResponseData ccUpdate(@RequestParam("type") Integer type,
                                 @RequestParam("id") Long id,
                                 @RequestParam("name") String name,
                                 @RequestParam("order") Integer order){
        HzFixedInformationDicEntity oldFixedInformationDic = fixedInformationDicService.getById(id);
        if(oldFixedInformationDic == null) return ResponseData.success("修改失败！",false);
        // 修改字体、书家名称需要对字帖字信息做同步修改操作
        if (!name.equals(oldFixedInformationDic.getFixedInformationContent())){
            // 修改
            switch (type) {
                case 1:
                    coChrInformationService.updateCharacterType(name);
                    break;
                case 2:
                    coChrInformationService.updateCalligrapher(name);
                    break;
                default:
                    return ResponseData.success("保存类别参数错误");
            }
        }
        HzFixedInformationDicEntity newFixedInformationDic = new HzFixedInformationDicEntity(id, name, new Date(), order);
        fixedInformationDicService.updateById(newFixedInformationDic);
        return ResponseData.success("修改成功");
    }

    /**
     * 字体、书家列表删除
     */
    @ApiOperation("字体、书家列表删除")
    @PostMapping("/cc/delete")
    public ResponseData ccDelete(@RequestBody Long[] ids){
        fixedInformationDicService.removeByIds(Arrays.asList(ids));
        // 暂未做同步处理
        return ResponseData.success("删除成功");
    }

}
